package cn.mayday.algorithms.year2021.month1.D链表和数组专题;

/**
 * 定义一个函数，输入一个链表的头节点，反转该链表并输出反转后链表的头节点。
 * <p>
 * 示例:
 * <p>
 * 输入: 1->2->3->4->5->NULL
 * 输出: 5->4->3->2->1->NULL
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 *
 * @author Mayday05
 * @date 2021/1/16 10:59
 */
public class Off024ReverseList {

    public static void main(String[] args) {

    }

    // 方法一： 直接循环
    // 复杂度分析
    //    时间复杂度：O(n)，其中n是链表的长度。需要遍历链表一次。
    //    空间复杂度：O(1)。
    public ListNode reverseList1(ListNode head) {
        if (head == null) {
            return null;
        }
        // 当前头节点
        ListNode currentNode = head;
        ListNode prev = null; // 缓存上一个节点值

        while (currentNode != null) {
            // 下一个节点-保存起来
            ListNode nextNode = currentNode.next;

            // 反转链表(当前节点指向前一个节点)
            currentNode.next = prev;
            prev = currentNode;

            currentNode = nextNode;
        }
        return prev;
    }


    // 方法二：递归
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode nextNode = head.next;
        ListNode newHead = reverseList(nextNode); // 递归

        nextNode.next = head;  // 互相指定一下头结点
        head.next = null; // 当前头结点指向Null
        return newHead;
    }


    // Definition for singly-linked list.
    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }
}
